'''Creates a new Dell self-dispatch support request, using a GUI.'''
import pprint
import itertools
import PySimpleGUI as sg
from warranty_manager.gui.confirmation import (
    get_confirmation, get_dell_request_confirmation
)
from warranty_manager.claim.dell.request_creator_layout import layout
from warranty_manager.claim.dell.common import get_access_token
from warranty_manager.claim.dell.handlers import (
    handle_load_parts,
    handle_add_part,
    handle_view_parts,
    handle_replace_parts,
    handle_remove_part,
    handle_add_note,
    handle_view_note,
    validate_common,
)
from warranty_manager.claim.dell.dispatch_api import get_address, create_dispatch


dispatch_code = None
part_nums_dict = {}

request_info = {
    'tag': None,
    'address': {'name': None},
    'phone': None,
    'po': None,
    'parts': [],
    'note': None,
    'drop ship': None,
    'adp': None,
}

window = sg.Window('Dell Self-Dispatch Request Creator', layout)

while True:
    event, values = window.read()

    if event in (None, 'Cancel'):
        break
    elif event == '-ADD_ADDRESS-':

        if get_confirmation('add a new address to the request'):

            if len(request_info['address']) > 1:
                sg.popup_error('You can only add one address at a time!', title='Error')
                continue
            else:
                request_info['address'] = {**request_info['address'], **get_address()}

                if len(request_info['address']) > 1:
                    window['-ADD_ADDRESS-'].update('Replace Address')

    elif event == '-VIEW_ADDRESS-':

        if len(request_info['address']) > 1:
            # To not display the address name in the popup
            sg.popup(
                f"Country ISO Code: {request_info['address']['iso']}\n"
                f"City: {request_info['address']['city']}\n"
                f"State: {request_info['address']['state']}\n"
                f"Zip Code: {request_info['address']['zip']}\n"
                f"Address Line 1: {request_info['address']['line 1']}\n"
                f"Address Line 2: {request_info['address']['line 2']}\n"
                f"Time Zone: {request_info['address']['zone']}",
                title='Address Details'
            )
        else:
            sg.popup_error('There is no address to view!', title='Error')
            continue

    elif event == '-REMOVE_ADDRESS-':

        if len(request_info['address']) == 1:
            sg.popup_error('There is no address to remove!', title='Error')
            continue
        elif get_confirmation('remove the current address from the request'):
            request_info['address'] = {'name': None}
            window['-ADD_ADDRESS-'].update('Add Address')
        else:
            continue

    elif event == '-LOAD_PARTS-':
        part_nums_dict = handle_load_parts(window)
    elif event == '-ADD_PART-':
        handle_add_part(window, part_nums_dict, request_info['parts'])
    elif event == '-VIEW_PARTS-':
        handle_view_parts(request_info['parts'])
    elif event == '-REMOVE_PART-':
        handle_remove_part(window, request_info['parts'])
    elif event == '-REPLACE_PARTS-':
        handle_replace_parts(window, part_nums_dict, request_info['parts'])
    elif event == '-ADD_NOTE-':
        request_info['note'] = handle_add_note(window, request_info['note'])
    elif event == '-VIEW_NOTE-':
        handle_view_note(request_info['note'])
    elif event == '-REMOVE_NOTE-':

        if not request_info['note']:
            sg.popup('There is no note to remove!', title='Info')
        elif get_confirmation('remove the note from the request'):
            request_info['note'] = ''
            window['-ADD_NOTE-'].update('Add Note')
        else:
            continue

    elif event == '-REPLACE_NOTE-':

        if not request_info['note']:
            sg.popup('There is no note to replace!', title='Info')
        elif get_confirmation('replace the current note with a new one'):
            request_info['note'] = ''
            request_info['note'] = handle_add_note(window, request_info['note'])
        else:
            continue

    elif event == '-CHANGE_MODEL-':
        confirmation = get_confirmation(
            'change the device model for this request, '
            'and set all model-specific fields back '
            'to their default values'
        )

        if confirmation:
            request_info['tag'] = None
            request_info['po'] = None
            request_info['parts'] = []
            request_info['note'] = ''
            part_nums_dict = None
            window['-ADD_PART-'].update('Add Part')
            window['-ADD_NOTE-'].update('Add Note')
            window['-LOAD_PARTS-'].update('Load Parts')
            window['-TAG-'].update('')
            window['-PO-'].update('')

    elif event == '-CREATE_REQUEST-':
        try:
            username, password, sandbox = validate_common(values)
        except TypeError:
            continue

        # Request Info
        tag = values['-TAG-'].strip()
        address_name = values['-ADDRESS-'].strip()
        phone = values['-PHONE-'].strip()
        po = values['-PO-'].strip()

        if not tag:
            sg.popup_error('You must enter a service tag!', title='Error')
            continue
        else:
            request_info['tag'] = tag

        # To make sure that either the address name or a full address is provided
        if not address_name and len(request_info['address']) == 1:
            sg.popup_error('You must enter an address name or full address!', title='Error')
            continue
        else:
            request_info['address']['name'] = address_name

        if not phone:
            sg.popup_error('You must enter a phone number!', title='Error')
            continue
        elif len(phone) != 10:
            sg.popup_error(
                'You must enter a phone number with ten digits!',
                title='Error'
            )
            continue
        else:
            try:
                int(phone)
            except ValueError:
                sg.popup_error(
                    'You must enter only numbers for the phone number!',
                    title='Error'
                )
                continue
            else:
                request_info['phone'] = phone

        if not po:
            sg.popup_error('You must enter a PO number!', title='Error')
            continue
        else:
            request_info['po'] = po

        if not request_info['note']:
            sg.popup_error('You must add at least one note!', title='Error')
            continue

        if len(request_info['parts']) == 0:
            sg.popup_error(
                'You must add at least one part number!',
                title='Error'
            )
            continue

        # GUI Checkboxes
        if not values['-DROP_SHIP-']:
            request_info['drop ship'] = 'false'
        else:
            request_info['drop ship'] = 'true'

        if not values['-ADP-']:
            request_info['adp'] = 'false'
        else:
            request_info['adp']  = 'true'

        # To create the claim
        if get_dell_request_confirmation(request_info, sandbox=sandbox):
            token = get_access_token('Dispatch', sandbox=sandbox)

            if token:
                dispatch_code = create_dispatch(
                    username,
                    password,
                    token,
                    request_info,
                    sandbox=sandbox,
                )

            # To clear any field that must change with each claim
            if dispatch_code:
                window['-TAG-'].update('')

                if not values['-MULTIPLE-']:
                    window['-PO-'].update('')

    else:
        continue

window.close()
